#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
提示词生成器主模块

该模块实现了提示词生成器的主类，整合了模板管理、信息融合、生成和优化功能。
"""

import sys
import os

# 添加项目根目录到Python路径
current_dir = os.path.dirname(os.path.abspath(__file__))
project_root = os.path.dirname(os.path.dirname(os.path.dirname(current_dir)))
sys.path.insert(0, project_root)

import logging
from typing import Dict, List, Optional, Set

# 现在尝试导入
import prompt_template_manager
import information_fusion_processor
import prompt_generation_engine
import prompt_optimizer
from src.config import config_manager

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)


class PromptGenerator:
    """
    提示词生成器主类
    
    整合了模板管理、信息融合、生成和优化功能，提供统一的接口来生成高质量的提示词。
    """
    
    def __init__(self):
        """
        初始化提示词生成器
        
        加载所有依赖的组件
        """
        # 加载各个组件
        self.template_manager = prompt_template_manager.get_prompt_template_manager()
        self.fusion_processor = information_fusion_processor.get_information_fusion_processor()
        self.generation_engine = prompt_generation_engine.get_prompt_generation_engine()
        self.optimizer = prompt_optimizer.get_prompt_optimizer()
        
        # 加载编码类目配置
        self.category_config = config_manager.CategoryConfigManager.get_instance()
        
        # 支持的编码类目列表
        self.supported_categories = ['scene_setting', 'theme_type', 'emotional_tendency', 
                                   'content_category', 'violence_level', 'sensitive_content', 'target_audience']
        
        logger.info("提示词生成器初始化完成")
        logger.info(f"支持的编码类目: {', '.join(self.supported_categories)}")
    
    def generate_prompt(self, video_id: str, vision_analysis_result: Dict, category: str, 
                       optimize: bool = True) -> str:
        """
        生成单个提示词
        
        Args:
            video_id: 视频ID
            vision_analysis_result: 视觉分析结果
            category: 编码类目
            optimize: 是否优化提示词
            
        Returns:
            生成的提示词
            
        Raises:
            ValueError: 当输入参数无效时
        """
        # 参数验证
        self._validate_parameters(video_id, vision_analysis_result, category)
        
        logger.info(f"生成提示词请求: 视频ID={video_id}, 类目={category}, 优化={optimize}")
        
        # 生成提示词
        prompt = self.generation_engine.generate_prompt(video_id, vision_analysis_result, category)
        
        # 验证生成的提示词
        if not self.generation_engine.validate_prompt(prompt):
            logger.warning("生成的提示词验证失败，尝试生成默认提示词")
            prompt = self.generation_engine._generate_default_prompt(category)
        
        # 优化提示词
        if optimize:
            prompt = self.optimizer.optimize_prompt(prompt, category)
        
        logger.info(f"提示词生成完成，长度: {len(prompt)} 字符")
        return prompt
    
    def generate_prompts_for_missing_categories(self, video_id: str, vision_analysis_result: Dict,
                                              optimize: bool = True) -> Dict[str, str]:
        """
        为所有需要补充的类目生成提示词
        
        Args:
            video_id: 视频ID
            vision_analysis_result: 视觉分析结果
            optimize: 是否优化提示词
            
        Returns:
            类目到提示词的映射
        """
        logger.info(f"为视频 {video_id} 生成缺失类目提示词")
        
        # 融合信息以确定需要补充的类目
        fusion_result = self.fusion_processor.fuse_information(video_id, vision_analysis_result)
        required_categories = fusion_result.get('required_categories', [])
        
        if not required_categories:
            logger.info(f"视频 {video_id} 没有需要补充的类目")
            return {}
        
        logger.info(f"需要补充的类目数量: {len(required_categories)}")
        
        # 批量生成提示词
        prompts = self.generation_engine.batch_generate_prompts(video_id, vision_analysis_result, required_categories)
        
        # 优化提示词
        if optimize:
            prompts = self.optimizer.batch_optimize(prompts)
        
        logger.info(f"缺失类目提示词生成完成，生成数量: {len(prompts)}")
        return prompts
    
    def generate_all_category_prompts(self, video_id: str, vision_analysis_result: Dict,
                                    categories: Optional[List[str]] = None,
                                    optimize: bool = True) -> Dict[str, str]:
        """
        为指定的所有类目生成提示词
        
        Args:
            video_id: 视频ID
            vision_analysis_result: 视觉分析结果
            categories: 要生成提示词的类目列表，如果为None则使用所有支持的类目
            optimize: 是否优化提示词
            
        Returns:
            类目到提示词的映射
        """
        # 确定要生成的类目列表
        target_categories = categories or self.supported_categories
        
        # 验证类目
        for category in target_categories:
            if category not in self.supported_categories:
                raise ValueError(f"不支持的编码类目: {category}")
        
        logger.info(f"为视频 {video_id} 生成所有类目提示词，类目数量: {len(target_categories)}")
        
        # 批量生成提示词
        prompts = self.generation_engine.batch_generate_prompts(video_id, vision_analysis_result, target_categories)
        
        # 优化提示词
        if optimize:
            prompts = self.optimizer.batch_optimize(prompts)
        
        # 验证所有生成的提示词
        valid_prompts = {}
        for category, prompt in prompts.items():
            if self.generation_engine.validate_prompt(prompt):
                valid_prompts[category] = prompt
            else:
                logger.warning(f"类目 {category} 的提示词验证失败，使用默认提示词")
                valid_prompts[category] = self.generation_engine._generate_default_prompt(category)
                if optimize:
                    valid_prompts[category] = self.optimizer.optimize_prompt(valid_prompts[category], category)
        
        logger.info(f"所有类目提示词生成完成，有效提示词数量: {len(valid_prompts)}")
        return valid_prompts
    
    def get_required_categories(self, video_id: str, vision_analysis_result: Dict) -> List[str]:
        """
        获取需要补充的类目列表
        
        Args:
            video_id: 视频ID
            vision_analysis_result: 视觉分析结果
            
        Returns:
            需要补充的类目列表
        """
        fusion_result = self.fusion_processor.fuse_information(video_id, vision_analysis_result)
        return fusion_result.get('required_categories', [])
    
    def validate_vision_result(self, vision_analysis_result: Dict) -> bool:
        """
        验证视觉分析结果是否有效
        
        Args:
            vision_analysis_result: 视觉分析结果
            
        Returns:
            视觉分析结果是否有效
        """
        if not isinstance(vision_analysis_result, dict):
            logger.error("视觉分析结果必须是字典类型")
            return False
        
        # 检查是否包含必要的字段
        # 这里可以根据实际需求添加更多的验证逻辑
        has_content = len(vision_analysis_result) > 0
        
        if not has_content:
            logger.error("视觉分析结果为空")
            return False
        
        logger.info("视觉分析结果验证通过")
        return True
    
    def _validate_parameters(self, video_id: str, vision_analysis_result: Dict, category: str) -> None:
        """
        验证输入参数
        
        Args:
            video_id: 视频ID
            vision_analysis_result: 视觉分析结果
            category: 编码类目
            
        Raises:
            ValueError: 当参数无效时
        """
        if not video_id or not isinstance(video_id, str):
            raise ValueError("视频ID必须是非空字符串")
        
        if not self.validate_vision_result(vision_analysis_result):
            raise ValueError("视觉分析结果无效")
        
        if not category or category not in self.supported_categories:
            raise ValueError(f"无效的编码类目: {category}。支持的类目: {', '.join(self.supported_categories)}")
    
    def get_supported_categories(self) -> List[str]:
        """
        获取支持的编码类目列表
        
        Returns:
            支持的编码类目列表
        """
        return self.supported_categories.copy()
    
    def generate_prompt_with_quality_feedback(self, video_id: str, vision_analysis_result: Dict,
                                            category: str, optimize: bool = True) -> Dict:
        """
        生成提示词并返回质量反馈
        
        Args:
            video_id: 视频ID
            vision_analysis_result: 视觉分析结果
            category: 编码类目
            optimize: 是否优化提示词
            
        Returns:
            包含提示词和质量指标的字典
        """
        # 生成提示词
        prompt = self.generate_prompt(video_id, vision_analysis_result, category, optimize)
        
        # 评估质量
        quality_metrics = self.optimizer.evaluate_prompt_quality(prompt, category)
        
        # 获取融合信息
        fusion_result = self.fusion_processor.fuse_information(video_id, vision_analysis_result)
        
        # 组装结果
        result = {
            'prompt': prompt,
            'quality_metrics': quality_metrics,
            'video_id': video_id,
            'category': category,
            'optimized': optimize,
            'used_vision_info': len(fusion_result.get('context_info', {})) > 0,
            'used_sample_data': fusion_result.get('used_sample_data', False)
        }
        
        logger.info(f"带质量反馈的提示词生成完成，整体质量: {quality_metrics['overall_quality']:.2f}")
        return result


# 单例模式访问函数
_prompt_generator_instance = None


def get_prompt_generator() -> PromptGenerator:
    """
    获取提示词生成器的单例实例
    
    Returns:
        PromptGenerator实例
    """
    global _prompt_generator_instance
    if _prompt_generator_instance is None:
        _prompt_generator_instance = PromptGenerator()
    return _prompt_generator_instance


# 测试代码
if __name__ == "__main__":
    # 配置日志
    logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    
    try:
        # 创建测试用的视觉分析结果
        test_vision_result = {
            'scene_setting': '校园场景',
            'key_elements': ['学生', '教室', '黑板', '讲台'],
            'description': '视频展示了一个典型的教室环境，学生们正在上课。'
        }
        
        # 获取生成器实例
        generator = get_prompt_generator()
        
        print("=== 测试1: 生成单个提示词 ===")
        prompt = generator.generate_prompt('video_001', test_vision_result, 'theme_type')
        print(f"生成的提示词:\n{prompt}")
        print(f"提示词长度: {len(prompt)} 字符")
        print()
        
        print("=== 测试2: 获取需要补充的类目 ===")
        required_cats = generator.get_required_categories('video_001', test_vision_result)
        print(f"需要补充的类目: {', '.join(required_cats)}")
        print()
        
        print("=== 测试3: 为缺失类目生成提示词 ===")
        missing_prompts = generator.generate_prompts_for_missing_categories('video_001', test_vision_result)
        print(f"生成的提示词数量: {len(missing_prompts)}")
        for cat, p in missing_prompts.items():
            print(f"\n类目 {cat} 的提示词:\n{p[:100]}...")  # 只打印前100个字符
        print()
        
        print("=== 测试4: 生成带质量反馈的提示词 ===")
        feedback = generator.generate_prompt_with_quality_feedback('video_001', test_vision_result, 'emotional_tendency')
        print(f"提示词质量: {feedback['quality_metrics']['overall_quality']:.2f}")
        print(f"使用了视觉信息: {feedback['used_vision_info']}")
        print(f"使用了样本数据: {feedback['used_sample_data']}")
        print()
        
    except Exception as e:
        logging.error(f"测试过程中发生错误: {str(e)}")
        raise